home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Mail / tnextmail / Source / batch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-06  |  5.2 KB  |  215 lines

  1. /* $Id: batch.c,v 1.3 91/05/25 15:32:20 cap Exp $
  2.  * Make a connection to tar, compress, and uuencode to batch up the 
  3.  * message and all its attachments.
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include <ctype.h>
  8. #include <sys/types.h>
  9. #ifdef USG
  10. #include <sys/unistd.h>
  11. #else
  12. #include <sys/param.h>
  13. #include <sys/file.h>
  14. #endif
  15. #include <sys/stat.h>
  16. #include "config.h"
  17. #include "tnextmail.h"
  18.  
  19. char command[MAXPATHLEN], attach_name[64], tar_uu_name[MAXPATHLEN];
  20. char **tolist;            /* list of addressees */
  21. char *construct_attach_header();
  22. extern int lastattach;
  23. extern struct attach *attachments;
  24.  
  25. /* 
  26.  * batch_message - make a system(3) call to tar, compress, and uuencode
  27.  *                 to create the body of the message to be mailed. 
  28.  *                 Output is written to the file tar.uu in the temp 
  29.  *                 directory.
  30.  */
  31.  
  32. batch_message(tmpdir_name)
  33.      char *tmpdir_name;
  34. {
  35.     sprintf(tar_uu_name, "%s/tar.uu", tmpdir_name);
  36.     sprintf(command, "%s cf - -C %s %s ", TAR, tmpdir_name, RTF_NAME);
  37.     construct_filelist();
  38.     strcat(command, "| compress | uuencode ");
  39.     construct_batch_name();
  40.     strcat(command, attach_name);
  41.     strcat(command, " > ");
  42.     strcat(command, tar_uu_name);
  43. #ifdef DEBUG
  44.     fprintf(stderr, "I will run \"%s\"\n", command);
  45. #endif
  46.     if (system(command) == 127) {
  47.     perror("batching");
  48.     fatalerrors++;
  49.     return;
  50.     }
  51. }
  52.  
  53. /* 
  54.  * construct_filelist - make a list of the form
  55.  *                      -C where index.rtf -C dir1 attach1
  56.  *                      where 'where' is the location of the rtf 
  57.  *                      file, index.rtf is the rtf file, dir1 is the 
  58.  *                      directory in which attach1 is located, etc.
  59.  */
  60.  
  61. construct_filelist()
  62. {
  63.     int i;
  64.     char *cend;
  65.  
  66.     for (i = 0; i < lastattach; i++) {
  67.     cend = &command[strlen(command)];
  68.     sprintf(cend, "-C %s %s ", attachments[i].pathname, attachments[i].basename);
  69.     }
  70. }
  71.  
  72. /* 
  73.  * construct_batch_name - make the weird file name from the subject 
  74.  *                        line. The weird name is placed in the 
  75.  *                        global variable attach_name.
  76.  */
  77.  
  78. construct_batch_name()
  79. {
  80.     int i;
  81.     char *sp = message_subject, *bp = attach_name;
  82.     
  83.     if (message_subject[0])
  84.     sp = message_subject;
  85.     else
  86.     sp = "No subject";
  87.     sprintf(bp, ".tar.%d.", getpid());
  88.     bp = &attach_name[strlen(attach_name)];
  89.     for (i = 0; i < 17 && *sp; i++, sp++) {
  90.     if (isalnum(*sp))
  91.         *bp++ = *sp;
  92.     else
  93.         *bp++ = '_';
  94.     }
  95.     strcpy(bp, ".attach");
  96. }
  97.  
  98. /* 
  99.  * check_file_access - make sure all attachments are readable. Print 
  100.  *                     out an error message and increment fatalerrors 
  101.  *                     for each unreadable file
  102.  */
  103.  
  104. check_file_access()
  105. {
  106.     int i;
  107.     char filename[MAXPATHLEN];
  108.     struct stat stbuf;
  109.  
  110.     for (i = 0; i < lastattach; i++) {
  111.     sprintf(filename, "%s%s", attachments[i].pathname,
  112.         attachments[i].basename);
  113.     if (access(filename, R_OK)) {
  114.         perror(filename);
  115.         fatalerrors++;
  116.     } else if (stat(filename, &stbuf)) {
  117.         perror(filename);
  118.         fatalerrors++;
  119.     }
  120. #if 0
  121.     /* 
  122.      * I'm not sure we want this restriction at all. For one 
  123.      * thing, NeXT mail allows you to attach directories.
  124.      * [cap 8/6/92]
  125.      */
  126.     else if (!(stbuf.st_mode & S_IFREG)) {
  127.         fprintf(stderr, "Cannot mail %s; can mail only regular files.\n",
  128.             filename);
  129.         fatalerrors++;
  130.     }
  131. #endif
  132.     }
  133. }
  134.  
  135. /* 
  136.  * construct_attach_header -
  137.  *     Make the "Next-Attachment:" line for the mail header. It is 
  138.  *     constructed in static string space, and a pointer to it is 
  139.  *     returned.
  140.  */
  141.  
  142. char *construct_attach_header()
  143. {
  144.     static char header[128];
  145.     struct stat stbuf;
  146.     long blocks;        /* weird NeXT blocks */
  147.  
  148.     if (stat(tar_uu_name, &stbuf)) {
  149.     perror(tar_uu_name);
  150.     fatalerrors++;
  151.     return NULL;
  152.     }
  153.     /* 
  154.      * I don't know what the blocks field is used for, but according 
  155.      * to NeXT's specifications, it should be ceil(stbuf.st_size / 48) * 66
  156.      */
  157.     blocks = stbuf.st_size / 48;
  158.     if (stbuf.st_size % 48)
  159.     blocks++;
  160.     blocks *= 66;
  161.     sprintf(header, "Next-Attachment: %s, %ld, 1/1, %ld, 0",
  162.         attach_name,
  163.         stbuf.st_size,
  164.         blocks);
  165.     return header;
  166. }
  167.  
  168. /* 
  169.  * mail_message - create the headers we add and send the message to 
  170.  *                the mailer.
  171.  */
  172.  
  173. mail_message(tmpdir_name)
  174.      char tmpdir_name[];
  175. {
  176.     char *attach_header = construct_attach_header();
  177.     char mailcmd[10240];
  178.     char **tp;
  179.     int c;
  180.     FILE *mailpipe, *message;
  181.  
  182.     strcpy(mailcmd, MAILER);
  183.     for (tp = tolist; *tp != NULL; tp++) {
  184.     strcat(mailcmd, " ");
  185.     strcat(mailcmd, *tp);
  186.     }
  187. #if 0
  188.     fprintf(stderr, "Mail command is \"%s\"\n", mailcmd);
  189.     sprintf(mailcmd, "cat > /tmp/sent_to_mailer");
  190. #endif
  191.     if ((mailpipe = popen(mailcmd, "w")) == NULL) {
  192.     perror(mailcmd);
  193.     fatalerrors++;
  194.     return;
  195.     }
  196.     fprintf(mailpipe, "To:");
  197.     for (tp = tolist; *tp != NULL; tp++)
  198.     fprintf(mailpipe, " %s", *tp);
  199.     if (message_subject[0])
  200.     fprintf(mailpipe, "\nSubject: %s\n", message_subject);
  201.     else
  202.     putc('\n', mailpipe);
  203.     fprintf(mailpipe, "%s\n\n", attach_header);
  204.     if ((message = fopen(tar_uu_name, "r")) == NULL) {
  205.     perror(tar_uu_name);
  206.     pclose(mailpipe);
  207.     fatalerrors++;
  208.     return;
  209.     }
  210.     while ((c = getc(message)) != EOF)
  211.     putc(c, mailpipe);
  212.     fclose(message);
  213.     pclose(mailpipe);
  214. }
  215.